<?php
class StringCommon {

	/**
	 * 获取字符串的长度
	 *
	 * 计算时, 汉字或全角字符占1个长度, 英文字符占0.5个长度
	 *
	 * @param string  $str
	 * @param boolean $filter 是否过滤html标签
	 * @return int 字符串的长度
	 */
	function get_str_length($str, $filter = false){
		if ($filter) {
			$str = html_entity_decode($str, ENT_QUOTES);
			$str = strip_tags($str);
		}
		return (strlen($str) + mb_strlen($str, 'UTF8')) / 4;
	}
	
	// 计算字符长度，含中文计算处理
	function iLength($str,$chtml=0){
		$num   =   0;
		$s   =   false;
		if ($chtml=1){
			$str=strip_tags($str);//去掉html
		}
		$len   =   strlen($str);
		for($i   =   0;$i   <   $len;$i++)   {
			if   ($str{$i}=="\t"   ||   $str{$i}=="\r"   ||   $str{$i}=="\n")continue;
			if   (ord($str{$i})   >   127)   {
				$s   =   !$s;
				if   ($s   ==   false)$num++;
				continue;
			}
			$num++;
		}
		return   $num;
	}
	
	function request_string($str) {
		import('ORG.Util.Input');
		//得到安全的数据
		$nstr=Input::getVar(trim($str));
		return $nstr;
	}
	
	function valididvalue($str){
		//取到正确ID值
		$vstr=common('String')->request_string($str);
		if(common('String')->str_type($vstr)!="f" || empty($vstr) ){
		 return false;
		}else{
		 return $vstr;
		}
	}
	
	/*  检测字符串类型   */
	//通过返回字符判断类型
	function str_type( $str ){
		$a=ereg('['.chr(0xa1).'-'.chr(0xff).']', $str); //匹配汉字
		$b=ereg('[0-9]', $str); //匹配数字
		$c=ereg('[a-zA-Z]', $str); //匹配英文
	
		if($a && $b && $c)
			return "a"; //汉字数字英文的混合字符串
		elseif($a && $b && !$c)
		return "b"; //汉字数字的混合字符串
		elseif($a && !$b && $c)
		return "c"; //汉字英文的混合字符串
		elseif(!$a && $b && $c)
		return "d"; //数字英文的混合字符串
		elseif($a && !$b && !$c)
		return "e"; //纯汉字
		elseif(!$a && $b && !$c)
		return "f"; //纯数字
		elseif(!$a && !$b && $c)
		return "g"; //纯英文
		else
			return "h"; //特殊字符
	}
	
	/**
	 +----------------------------------------------------------
	 * 字符串截取，支持中文和其它编码
	 +----------------------------------------------------------
	 * @static
	 * @access public
	 +----------------------------------------------------------
	 * @param string $str 需要转换的字符串
	 * @param string $length 截取长度
	 * @param string $charset 编码格式
	 * @param string $suffix 截断显示字符
	 +----------------------------------------------------------
	 * @return string
	 +----------------------------------------------------------
	 */
	function mStr($str, $length, $charset = "utf-8", $suffix = true) {
		return common('String')->msubstr($str, 0, $length, $charset, $suffix);
	}
	
	/**
	 * +----------------------------------------------------------
	 * 字符串截取，支持中文和其它编码
	 * +----------------------------------------------------------
	 *
	 * @static
	 *
	 * @access public
	 *         +----------------------------------------------------------
	 * @param string $str
	 *        	需要转换的字符串
	 * @param string $start
	 *        	开始位置
	 * @param string $length
	 *        	截取长度
	 * @param string $charset
	 *        	编码格式
	 * @param string $suffix
	 *        	截断显示字符
	 *        	+----------------------------------------------------------
	 * @return string
	 *         +----------------------------------------------------------
	 */
	function msubstr($str, $start = 0, $length, $charset = "utf-8", $suffix = true, $text) {
		if (function_exists ( "mb_substr" ))
			$slice = mb_substr ( $str, $start, $length, $charset );
		elseif (function_exists ( 'iconv_substr' )) {
			$slice = iconv_substr ( $str, $start, $length, $charset );
		} else {
			$re ['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
			$re ['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
			$re ['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
			$re ['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
			preg_match_all ( $re [$charset], $str, $match );
			$slice = join ( "", array_slice ( $match [0], $start, $length ) );
		}
		if ($suffix && $str != $slice)
			return $slice . (isset($text) ? $text : "...");
		return $slice;
	}
	
	/**
	 * 增强反序列化问题，系统预设的unserialize在反序列化脚本标签时候返回false
	 */
	function unserialize_plus($in_str) {
		$out_str = preg_replace ( '!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $in_str );
		return unserialize ( $out_str );
	}
	
	/**
	 * 格式化评论, 替换表情和@用户
	 * M2
	 * @param string $content 待格式化的内容
	 * @param boolean $url 是否替换URL
	 * @return string
	 */
	function formatComment($content,$url=false){
		if($url){
			$content = preg_replace('/((?:https?|ftp):\/\/(?:www\.)?(?:[a-zA-Z0-9][a-zA-Z0-9\-]*\.)?[a-zA-Z0-9][a-zA-Z0-9\-]*(?:\.[a-zA-Z0-9]+)+(?:\:[0-9]*)?(?:\/[^\x{2e80}-\x{9fff}\s<\'\"“”‘’]*)?)/u', '<a href="\1" target="_blank">\1</a>\2', $content);
		}
		$content = str_ireplace("&#091;", '[', $content);
		$content = str_ireplace("&#093;", ']', $content);
		$content = preg_replace_callback("/(\[.+?\])/is",replaceEmot,$content);
		$content = preg_replace_callback("/@([\w\x{2e80}-\x{9fff}\-]+)/u",getUserId,$content);
		return $content;
	}
	
	/**
	 * 获取用户姓名
	 * M2
	 * @param int $uid 用户ID
	 * @return string 返回用户姓名
	 */
	function getUserName($uid,$lang='zh') {
		global $yl;
		if ($uid == $yl['user']['uid'] || $uid == $yl['user']['uname'])
			return $yl['user']['uname'];
		static $_MapName = array();
		if(!isset($_MapName[$uid])){
			if(is_numeric($uid)){
				$userinfo = model('User')->getUserByIdentifier($uid, 'uid');
			}else{
				$userinfo = model('User')->getUserByIdentifier($uid, 'uname');
			}
			$_MapName[$uid] = $userinfo['uname'];
		}
		return htmlspecialchars($_MapName[$uid]);
	}
	
	/**
	 * 获取缩短后的字符串
	 * M2
	 * @param string $str 要缩短的字符串
	 * @param int $length 超过的字符数
	 * @param string $ext 代替的字符
	 * @return string 返回缩短后的字符串
	 */
	function getShort($str, $length = 40, $ext = '') {
		$str	=	htmlspecialchars($str);
		$str	=	strip_tags($str);
		$str	=	htmlspecialchars_decode($str);
		$strlenth	=	0;
		$out		=	'';
		preg_match_all("/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/", $str, $match);
		foreach($match[0] as $v){
			preg_match("/[\xe0-\xef][\x80-\xbf]{2}/",$v, $matchs);
			if(!empty($matchs[0])){
				$strlenth	+=	1;
			}elseif(is_numeric($v)){
				$strlenth	+=	0.5;    // 字符字节长度比例 汉字为1
			}else{
				$strlenth	+=	0.5;    // 字符字节长度比例 汉字为1
			}
			if ($strlenth > $length) {
				$output .= $ext;
				break;
			}
			$output	.=	$v;
		}
		return $output;
	}
	
	/**
	 * 格式化微博,替换表情/@用户/话题
	 * M2
	 * @param string  $content 待格式化的内容
	 * @param boolean $url     是否替换URL
	 * @return string
	 */
	function format($content,$url=false){
		if($url){
			$content = preg_replace('/((?:https?|ftp):\/\/(?:www\.)?(?:[a-zA-Z0-9][a-zA-Z0-9\-]*\.)?[a-zA-Z0-9][a-zA-Z0-9\-]*(?:\.[a-zA-Z0-9]+)+(?:\:[0-9]*)?(?:\/[^\x{2e80}-\x{9fff}\s<\'\"“”‘’]*)?)/u', '<a href="\1" target="_blank">\1</a>\2', $content);
		}
		$content = preg_replace_callback("/(?:#[^#]*[^#^\s][^#]*#|(\[.+?\]))/is",replaceEmot,$content);
		$content = preg_replace_callback("/#([^#]*[^#^\s][^#]*)#/is",themeformat,$content);
		$content = preg_replace_callback("/(\[.+?\])/is",replaceEmot,$content);
		$content = preg_replace_callback("/@([\w\x{2e80}-\x{9fff}\-]+)/u",getUserId,$content);
		return $content;
	}
	
	/**
	 * 表情替换 [格式化微博与格式化评论专用]
	 * M2
	 * @param array $data
	 */
	function replaceEmot($data) {
		if(preg_match("/#.+#/i",$data[0])) {
			return $data[0];
		}
		$info = model('Expression')->getExpressionDetailByEmotion($data[1]);
		if($info) {
			return preg_replace("/\[.+?\]/i","<img src='".__ROOT__."/Public/expression/".$info['type']."/".$info['filename']."' />",$data[0]);
		}else {
			return $data[0];
		}
	}
	
	/**
	 * 话题替换 [格式化微博专用]
	 *
	 * @param array $data
	 * @see format()
	 */
	function themeformat($data){
		return "<a href=".U('home/user/topics',array('k'=>urlencode($data[1]))).">".$data[0]."</a>";
	}
	
	/**
	 * 根据用户昵称获取用户ID [格式化微博与格式化评论专用]
	 * M2
	 * @param array $name 用户昵称
	 */
	function getUserId($name) {
		$info = model('User')->getUserByIdentifier($name[1], 'uname');
		if ($info) {
			return common('String')->getUserSpace($info['uid'], 'null', '_blank', "$name[0]", false);
		}else {
			return "<a href=".URL('home/user/searchuser',array('k'=>urlencode($name[1])))." target=\"_blank\">".$name[0]."</a>";
		}
	}
	
	/**
	 * 返回解析的空间地址
	 * M2
	 * @param int $uid 用户ID
	 * @param string $class class样式
	 * @param string $target 跳转方式
	 * @param string $text 用户头像
	 * @param boolean $icon
	 * @return string 返回解析的空间地址
	 */
	function getUserSpace($uid, $class, $target, $text, $icon = true, $user_name, $showcard) {
		static $_userinfo = array ();
		if (!isset ($_userinfo[$uid])) {
			$_userinfo[$uid] = model('User')->getUserByIdentifier($uid, 'uid');
		}
		$target = ($target) ? $target : '_self';
		$text = ($text) ? $text : $_userinfo[$uid]['uname'];
		if ($icon) {
			$user_name_end = null;
		}
		if(session('?mid')) {
			if(session('mid') != $uid) {
				if ($showcard) {
					$showcard = "onmouseover='card.showCard(this,".$uid.")'";
				}
			}
		} else {
			if ($showcard) {
				$showcard = "onmouseover='card.showCard(this,".$uid.")'";
			}
		}
		if ($_userinfo[$uid]['domain'])
			$url = URL('home/Space/index',array('uid'=>$_userinfo[$uid]['domain']));
		else
			$url = URL('home/Space/index',array('uid'=>$uid));
		$user_space_info = "<a href='{$url}' class='{$class}' target='{$target}' {$showcard}>$text" . $user_name_end . "</a>";
		return $user_space_info;
	}
	
	/**
	 * 随机密钥长度 取值 0-32;
	 * 加入随机密钥，可以令密文无任何规律，即便是原文和密钥完全相同，加密结果也会每次不同，增大破解难度。
 	 * 取值越大，密文变动规律越大，密文变化 = 16 的 $ckey_length 次方
	 * 当此值为 0 时，则不产生随机密钥
	 * M2
	 * @param
	 */
	function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
	
		$ckey_length = 4;	
		$key = md5($key ? $key : 'abc123456');
		$keya = md5(substr($key, 0, 16));
		$keyb = md5(substr($key, 16, 16));
		$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
	
		$cryptkey = $keya.md5($keya.$keyc);
		$key_length = strlen($cryptkey);
	
		$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
		$string_length = strlen($string);
	
		$result = '';
		$box = range(0, 255);
	
		$rndkey = array();
		for($i = 0; $i <= 255; $i++) {
			$rndkey[$i] = ord($cryptkey[$i % $key_length]);
		}
	
		for($j = $i = 0; $i < 256; $i++) {
			$j = ($j + $box[$i] + $rndkey[$i]) % 256;
			$tmp = $box[$i];
			$box[$i] = $box[$j];
			$box[$j] = $tmp;
		}
	
		for($a = $j = $i = 0; $i < $string_length; $i++) {
			$a = ($a + 1) % 256;
			$j = ($j + $box[$a]) % 256;
			$tmp = $box[$a];
			$box[$a] = $box[$j];
			$box[$j] = $tmp;
			$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
		}
	
		if($operation == 'DECODE') {
			if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
				return substr($result, 26);
			} else {
				return '';
			}
		} else {
			return $keyc.str_replace('=', '', base64_encode($result));
		}
	}
	
	function getgpc($k, $t='R') {
		switch($t) {
			case 'P': $var = &$_POST; break;
			case 'G': $var = &$_GET; break;
			case 'C': $var = &$_COOKIE; break;
			case 'R': $var = &$_REQUEST; break;
		}
		return isset($var[$k]) ? (is_array($var[$k]) ? $var[$k] : trim($var[$k])) : NULL;
	}
	
	/**
	 * 关键字过滤
	 * M2
	 * @param string $content 过滤的内容
	 * @return string 返回过滤后的内容
	 */
	function keyWordFilter( $content ){
		$audit = model('Data')->lget('audit');
		if($audit['open'] && $audit['keywords']){
			$replace = $audit['replace']?$audit['replace']:'[*和谐]';
			$arr_keyword = explode('|', $audit['keywords']);
			foreach ( $arr_keyword as $k=>$v ){
				$content = str_replace($v, $replace, $content);
			}
			return $content;
		}else{
			return $content;
		}
	}
	function getSex($sex) {
		if($sex == '0') 
			return '<a href="#" title="女"><i class="icon-woman"></i></a>';
		elseif($sex == '1')
			return '<a href="#" title="男"><i class="icon-man"></i></a>';
	}
	
	/**
	 * Get next UUID
	 *
	 * @return integer
	 */
	function getUUID(){
		if (function_exists('com_create_guid')){
			return trim(com_create_guid(),'{}');
		}else{
			mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
			$charid = strtoupper(md5(uniqid(rand(), true)));			
			$uuid = substr($charid, 0, 8).substr($charid, 8, 4)
			.substr($charid,12, 4).substr($charid,16, 4).substr($charid,20,12);
			return $uuid;
		}
	}
}
?>